package com.campus.backend.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.campus.backend.bean.statistics.StatisticsQueryParam;
import com.campus.backend.entity.Order;
import com.campus.backend.mapper.OrderMapper;
import com.campus.backend.vo.statistics.OrderStatisticsVo;
import com.campus.backend.vo.statistics.RevenueStatisticsVo;
import com.campus.common.enums.OrderStatusEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 数据统计 服务实现类
 * </p>
 *
 * @author ZhaoYuJie
 * @since 2025-05-21
 */
@Service
public class StatisticsService {

    @Autowired
    private OrderMapper orderMapper;

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    /**
     * 获取订单统计数据
     *
     * @param param 查询参数
     * @return 订单统计数据列表
     */
    public List<OrderStatisticsVo> getOrderStatistics(StatisticsQueryParam param) {
        // 获取日期范围内的所有日期
        List<LocalDate> dateList = getDateRange(param.getStartDate(), param.getEndDate());
        
        // 查询已完成订单
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getStatus, OrderStatusEnum.COMPLETED.getValue()) // 状态为已完成
                .ge(Order::getCreateTime, LocalDateTime.of(param.getStartDate(), LocalTime.MIN))
                .le(Order::getCreateTime, LocalDateTime.of(param.getEndDate(), LocalTime.MAX));
        
        List<Order> orders = orderMapper.selectList(wrapper);
        
        // 按日期分组统计订单数量
        Map<String, Integer> orderCountMap = new HashMap<>();
        for (Order order : orders) {
            String dateStr = order.getCreateTime().format(DATE_FORMATTER);
            orderCountMap.put(dateStr, orderCountMap.getOrDefault(dateStr, 0) + 1);
        }
        
        // 构建返回结果
        List<OrderStatisticsVo> result = new ArrayList<>();
        for (LocalDate date : dateList) {
            String dateStr = date.format(DATE_FORMATTER);
            OrderStatisticsVo vo = new OrderStatisticsVo();
            vo.setDate(dateStr);
            vo.setOrderCount(orderCountMap.getOrDefault(dateStr, 0));
            result.add(vo);
        }
        
        return result;
    }

    /**
     * 获取商户营收分析数据
     *
     * @param param 查询参数
     * @return 商户营收分析数据列表
     */
    public List<RevenueStatisticsVo> getMerchantRevenue(StatisticsQueryParam param) {
        // 获取日期范围内的所有日期
        List<LocalDate> dateList = getDateRange(param.getStartDate(), param.getEndDate());
        
        // 查询已结算订单
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getProfitSettled, 1) // 已结算
                .ge(Order::getCreateTime, LocalDateTime.of(param.getStartDate(), LocalTime.MIN))
                .le(Order::getCreateTime, LocalDateTime.of(param.getEndDate(), LocalTime.MAX));
        
        List<Order> orders = orderMapper.selectList(wrapper);
        
        // 按日期分组统计商户收益
        Map<String, BigDecimal> revenueMap = new HashMap<>();
        for (Order order : orders) {
            String dateStr = order.getCreateTime().format(DATE_FORMATTER);
            BigDecimal currentRevenue = revenueMap.getOrDefault(dateStr, BigDecimal.ZERO);
            revenueMap.put(dateStr, currentRevenue.add(order.getMerchantProfit()));
        }
        
        // 构建返回结果
        List<RevenueStatisticsVo> result = new ArrayList<>();
        for (LocalDate date : dateList) {
            String dateStr = date.format(DATE_FORMATTER);
            RevenueStatisticsVo vo = new RevenueStatisticsVo();
            vo.setDate(dateStr);
            vo.setRevenue(revenueMap.getOrDefault(dateStr, BigDecimal.ZERO));
            result.add(vo);
        }
        
        return result;
    }

    /**
     * 获取平台营收分析数据
     *
     * @param param 查询参数
     * @return 平台营收分析数据列表
     */
    public List<RevenueStatisticsVo> getPlatformRevenue(StatisticsQueryParam param) {
        // 获取日期范围内的所有日期
        List<LocalDate> dateList = getDateRange(param.getStartDate(), param.getEndDate());
        
        // 查询已结算订单
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getProfitSettled, 1) // 已结算
                .ge(Order::getCreateTime, LocalDateTime.of(param.getStartDate(), LocalTime.MIN))
                .le(Order::getCreateTime, LocalDateTime.of(param.getEndDate(), LocalTime.MAX));
        
        List<Order> orders = orderMapper.selectList(wrapper);
        
        // 按日期分组统计平台收益
        Map<String, BigDecimal> revenueMap = new HashMap<>();
        for (Order order : orders) {
            String dateStr = order.getCreateTime().format(DATE_FORMATTER);
            BigDecimal currentRevenue = revenueMap.getOrDefault(dateStr, BigDecimal.ZERO);
            revenueMap.put(dateStr, currentRevenue.add(order.getPlatformProfit()));
        }
        
        // 构建返回结果
        List<RevenueStatisticsVo> result = new ArrayList<>();
        for (LocalDate date : dateList) {
            String dateStr = date.format(DATE_FORMATTER);
            RevenueStatisticsVo vo = new RevenueStatisticsVo();
            vo.setDate(dateStr);
            vo.setRevenue(revenueMap.getOrDefault(dateStr, BigDecimal.ZERO));
            result.add(vo);
        }
        
        return result;
    }

    /**
     * 获取日期范围内的所有日期
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 日期列表
     */
    private List<LocalDate> getDateRange(LocalDate startDate, LocalDate endDate) {
        List<LocalDate> dateList = new ArrayList<>();
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            dateList.add(currentDate);
            currentDate = currentDate.plusDays(1);
        }
        return dateList;
    }
}